/*
 * @Author: Broin
 * @Date: 2021-11-08 21:44:04
 * @LastEditTime: 2022-01-13 10:11:20
 * @LastEditors: your name
 * @Description: 
 * @FilePath: /myCore/os/src/main.rs
 * MADE BY BROIN
 */

#![no_std]
#![no_main]
#![feature(panic_info_message)]

#[macro_use]
mod console;
mod logging;
mod lang_items;
mod sbi;

use log::*;

use core::arch::global_asm;
global_asm!(include_str!("entry.asm"));

fn clear_bss() {
    extern "C" {
        fn sbss();
        fn ebss();
    }
    (sbss as usize..ebss as usize).for_each(|a|{
        unsafe {
            (a as *mut u8).write_volatile(0)
        }
    });
}

#[no_mangle]
pub fn rust_main() -> ! {
    extern "C" {
        fn stext();
        fn etext();
        fn srodata();
        fn erodata();
        fn sdata();
        fn edata();
        fn sbss();
        fn ebss();
        fn boot_stack();
        fn boot_stack_top();
    }
    clear_bss();
    logging::init();
    warn!("Deallocate frame: {:#x}", stext as usize);

    info!(".text [{:#x}, {:#x})", stext as usize, etext as usize);
    debug!(".rodata [{:#x}, {:#x})", srodata as usize, erodata as usize);
    trace!(".data [{:#x}, {:#x})", sdata as usize, edata as usize);
    error!(
        "boot_stack [{:#x}, {:#x})",
        boot_stack as usize, boot_stack_top as usize
    );
    error!(".bss [{:#x}, {:#x})", sbss as usize, ebss as usize);
    panic!("YEAH~shutdown");
}



// #![feature(llvm_asm)]

// use core::fmt::{self, Write};

// use crate::sbi::shutdown;
// struct Stdout;

// mod lang_items;
// mod sbi;

// const SYSCALL_EXIT: usize = 93;
// const SYSCALL_WRITE: usize = 64;

// fn syscall(id: usize, args: [usize; 3]) -> isize {
//     let mut ret: isize;
//     unsafe {
//         llvm_asm!("ecall"
//             : "={x10}" (ret)
//             : "{x10}" (args[0]), "{x11}" (args[1]), "{x12}" (args[2]), "{x17}" (id)
//             : "memory"
//             : "volatile"
//         );
//     }
//     ret
// }

// //Systemcall for write.
// pub fn sys_write(fd: usize, buffer: &[u8]) -> isize {
//     syscall(SYSCALL_WRITE, [fd, buffer.as_ptr() as usize, buffer.len()])
// }


// //Systemcall for exit.
// pub fn sys_exit(xstate: i32) -> isize {
//     syscall(SYSCALL_EXIT, [xstate as usize, 0, 0])
// }


// pub fn print(args: fmt::Arguments){
//     Stdout.write_fmt(args).unwrap();
// }



// #[macro_export]
// macro_rules! print {
//     ($fmt: literal $(, $($arg: tt)+)?) => {
//         $crate::console::print(format_args!($fmt $(, $(arg)+)?));
//     };
// }

// #[macro_export]
// macro_rules! println {
//     ($fmt: literal $(, $($arg: tt)+)?) => {
//         print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?));
//     };
// }

// #[no_mangle]
// extern "C" fn _start() {
//     //loop{};
//     println!("Hello world!");
//     shutdown();
// }
// impl Write for Stdout {
//     fn write_str(&mut self, s: &str) -> fmt::Result {
//         sys_write(1, s.as_bytes());
//         Ok(())
//     }
//     fn write_char(&mut self, c: char) -> fmt::Result {
//         self.write_str(c.encode_utf8(&mut [0; 4]))
//     }

//     fn write_fmt(mut self: &mut Self, args: fmt::Arguments<'_>) -> fmt::Result {
//         fmt::write(&mut self, args)
//     }
// }